/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test.shanika;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.FrameGrabber.Exception;
import com.googlecode.javacv.VideoInputFrameGrabber;
import com.googlecode.javacv.cpp.opencv_imgproc.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import objectExtraction.HSVSkinDetector;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;

/**
 *
 * @author HOME
 */
public class Backie {

    private IplImage image, bg, foreground, gray_image, gray_bg;
//    CanvasFrame canv0 = new CanvasFrame("Image0");
//    CanvasFrame canv1 = new CanvasFrame("Image1");
//    CanvasFrame canv2 = new CanvasFrame("Image2");
//    CanvasFrame canv3 = new CanvasFrame("Image3");
//    CanvasFrame canv4 = new CanvasFrame("Image4");
//    CanvasFrame canv2 = new CanvasFrame("temp1");
//    CanvasFrame canv3 = new CanvasFrame("temp3");

    public static void main(String[] args) {
        try {

            CanvasFrame can = new CanvasFrame("Org Image");
            CanvasFrame can2 = new CanvasFrame("Background");
            CanvasFrame can3 = new CanvasFrame("foreground");
            Backie b = new Backie();
            FrameGrabber grabber = new VideoInputFrameGrabber(0);
            IplImage[] imarr = new IplImage[5];


            grabber.start();
            Thread.sleep(1000);

//            for (int i = 0; i < 5; i++) {
//                IplImage im1 = grabber.grab();
//                imarr[i] = im1;
//                System.out.println("array Done" + i);
//                //    cvReleaseImage(im1);
//            }
//            b.average(imarr);

            IplImage im1 = grabber.grab();
            b.setBackground(im1);

            while (true) {

                IplImage im = grabber.grab();
                can.showImage(im);

           

                IplImage forg = b.getForeGround(im);
                can3.showImage(forg);

                IplImage bag = b.getBackground();
                can2.showImage(bag);

            }
        } catch (InterruptedException ex) {
            Logger.getLogger(Backie.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Backie.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public IplImage getForeGround(IplImage img) {

        gray_image = cvCreateImage(cvGetSize(img), 8, 1);
        foreground = cvCreateImage(cvGetSize(img), 8, 1);
        image = cvCreateImage(cvGetSize(img), 8, 1);
        //    image = this.backprojection(img);
        gray_image = new HSVSkinDetector().getHSVSkin(img);
        ///     cvConvertScale(gray_image, image, 0.5, 128);
        //    cvCvtColor(img, gray_image, CV_BGR2GRAY); // Get gray scale image
        //   cvEqualizeHist(gray_image, gray_image); // Histogram Equilizer: To adjust brightness
       cvSmooth(gray_image, gray_image, CV_BLUR, 1);
        //  can.showImage(gray_image);
        //    can2.showImage(bg);


    cvSub(gray_image, bg, foreground, image);

     //   cvAbsDiff(gray_image, bg, foreground); // Absolute Difference
        IplConvKernel se = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_ELLIPSE, null); // Struncturing Element
        IplConvKernel se1 = cvCreateStructuringElementEx(7, 7, 3, 3, CV_SHAPE_ELLIPSE, null); // Struncturing Element

        cvMorphologyEx(foreground, foreground, image, se, CV_MOP_CLOSE, 1);
        cvMorphologyEx(foreground, foreground, image, se1, CV_MOP_OPEN, 2);
// cvThreshold(foreground, foreground, 60, 255, CV_THRESH_BINARY); // thresholding

////

//////        //   cvAdaptiveThreshold(foreground, foreground, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 0);
//////

//        cvMorphologyEx(foreground, foreground, image, se, CV_MOP_GRADIENT, 1);
        //  can3.showImage(foreground);
        cvReleaseImage(gray_image);
//        cvReleaseImage(bg);
        return foreground;
    }

    public void setBackground(IplImage background) {
        //   image = cvCreateImage(cvGetSize(background), 8, 1);
        //     bg = normImage;
        gray_bg = cvCreateImage(cvGetSize(background), 8, 1);
        //  bg = cvCreateImage(cvGetSize(background), 8, 1);

        IplImage backproject = cvCreateImage(cvGetSize(background), 8, 1);
        //  backproject = this.backprojection(background);

        gray_bg = new HSVSkinDetector().getHSVSkin(background);
        //    cvConvertScale(gray_bg, backproject, 0.5, 0);

        // cvCvtColor(bg, gray_bg, CV_BGR2GRAY); // Get gray scale image of Background
        //  cvEqualizeHist(gray_bg, gray_bg); // Histogram Equilizer: To adjust brightness
       //     cvSmooth(gray_bg, gray_bg, CV_MEDIAN, 5);

//        IplConvKernel se = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_ELLIPSE, null); // Struncturing Element
//        IplConvKernel se1 = cvCreateStructuringElementEx(7, 7, 3, 3, CV_SHAPE_ELLIPSE, null); // Struncturing Element
//
//        cvMorphologyEx(gray_bg, gray_bg, image, se, CV_MOP_CLOSE, 1);
//        cvMorphologyEx(gray_bg, gray_bg, image, se1, CV_MOP_OPEN, 2);

        bg = gray_bg;
        //  bg=backproject;

        //    cvReleaseImage(gray_bg);

    }

    public IplImage getBackground() {
        return bg;
    }

    public IplImageArray splitChannels(IplImage hsvImage) {

        CvSize size = hsvImage.cvSize();
        int depth = hsvImage.depth();
        IplImage channel0 = cvCreateImage(size, depth, 1);
        IplImage channel1 = cvCreateImage(size, depth, 1);
        IplImage channel2 = cvCreateImage(size, depth, 1);

        //   hueI.showImage(channel0);
        cvSplit(hsvImage, channel0, channel1, channel2, null);
        return new IplImageArray(channel0, channel1, channel2);
    }

    public IplImage backprojection(IplImage normImage) {

        int numberOfBins = 255; // should be changed
        float minRange = 1f;
        float maxRange = 254f;

        // Allocate histogram object
        int dims = 1;
        int[] sizes = new int[]{numberOfBins};
        int histType = CV_HIST_ARRAY;
        float[] minMax = new float[]{minRange, maxRange};
        float[][] ranges = new float[][]{minMax};
        int uniform = 1;

        IplImageArray imarr = this.splitChannels(normImage);

        CvHistogram hist = cvCreateHist(dims, sizes, histType, ranges, uniform);

        // Compute histogram
        int accumulate = 1;
        IplImage mask = null;
        cvCalcHist(imarr, hist, accumulate, null);

        // Normalize the Histogram

        cvNormalizeHist(hist, 32);

        /// Get Backprojection

        IplImage backproject = cvCreateImage(normImage.cvSize(), 8, 3);
        //    IplImage suppImage = cvCreateImage(normImage.cvSize(), 8, 1);

        cvCalcBackProject(imarr, backproject, hist);
        cvReleaseHist(hist);

        return backproject;
    }

//    public void average(IplImage[] image1) {
//
//        HSVSkinDetector hsv = new HSVSkinDetector();
//
//        IplImage im = image1[0];
//        IplImage mask = cvCreateImage(cvGetSize(im), 8, 1);
//        IplImage skin = cvCreateImage(cvGetSize(im), 8, 1);
//        IplImage skin2 = cvCreateImage(cvGetSize(im), 8, 1);
//        IplImage result = cvCreateImage(cvGetSize(im), 8, 1);
//        // cvZero(result);
//
//        for (int i = 0; i < 5; i++) {
//
//            canv2.showImage(image1[i]);
//            skin = hsv.getHSVSkin(image1[i]);
//            canv3.showImage(skin);
//            cvAdd(skin, result, result, mask);
//            canv1.showImage(result);
//            System.out.println("average array done" + i);
//        }
//
//        cvConvertScale(result, result, 0.2, 0);
//        canv0.showImage(result);
//        System.out.println("Done result");
//    }
}
